package cmich.cps.scheduler.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;

import cmich.cps.scheduler.SchedulingSystem;
import cmich.cps.scheduler.data.Schedule;

/**
 * The Class ScheduleController.
 * 
 * @author Jonathan Kissinger <kissi1j@cmich.edu>
 */
public class ScheduleController implements Controller {

	/** The table. */
	private final JTable table;

	/** The model. */
	private DefaultTableModel model;

	/** The system. */
	private SchedulingSystem system = SchedulingSystem.getInstance();

	/** The frame. */
	private Frame frame = Frame.getInstance();

	/**
	 * Instantiates a new schedule controller.
	 *
	 * @param table the table
	 */
	ScheduleController(JTable table) {
		this.table = table;
		String[] headers = { "Id", "Date Generated", "Algorithm Used", "Value", "Theoretical Max Value", "Percentage" };
		this.model = new DefaultTableModel(new Object[][] {}, headers ) {
			private static final long serialVersionUID = 1L;

			@Override
			public boolean isCellEditable(int rowIndex, int mColIndex) {
				return false;
			}

			@Override  
			public Class<?> getColumnClass(int col) {  
				if(col == 2) {
					return Integer.class;
				}
				else {
					return String.class;  
				}
			}
		};
		table.setModel(this.model);
		this.table.setAutoCreateRowSorter(true);
		this.table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		this.table.getTableHeader().setReorderingAllowed(false);
	}

	/* (non-Javadoc)
	 * @see cmich.cps.scheduler.gui.Controller#populate()
	 */
	public void populate() {
		model.setRowCount(0);
		for(Schedule s : system.getSchedules()) {
			int percent = (int) (((float) s.getValue() / (float) s.getTheoreticalMax())*10000);
			String percentage = (percent / 100) + "." + (percent % 100) + "%";
			model.addRow(new Object[] { s.getId(), s.getTimestamp(), s.getAlgorithmUsed(), s.getValue(), s.getTheoreticalMax(), percentage });
		}
	}

	/* (non-Javadoc)
	 * @see cmich.cps.scheduler.gui.Controller#addFunctionality()
	 */
	public void addFunctionality() {
		table.addMouseListener(new TableMenu());
		table.getParent().addMouseListener(new TableMenu());
	}

	/**
	 * @author Jonathan Kissinger <kissi1j@cmich.edu>
	 * 
	 * The Class TableMenu.
	 */
	private class TableMenu extends MouseAdapter {

		/* (non-Javadoc)
		 * @see java.awt.event.MouseAdapter#mouseReleased(java.awt.event.MouseEvent)
		 */
		@Override
		public void mouseReleased(MouseEvent e) {
			if (e.isPopupTrigger()) {
				JPopupMenu popup = new JPopupMenu();
				JMenuItem generateKBItem = new JMenuItem("Generate schedule with KruskalBased algorithm");
				generateKBItem.addActionListener(new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent e) {
						frame.startKruskalBased();
					}
				});
				popup.add(generateKBItem);
				JMenuItem generateHItem = new JMenuItem("Generate schedule with Hybrid algorithm");
				generateHItem.addActionListener(new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent e) {
						frame.startHybrid();
					}
				});
				popup.add(generateHItem);
				JMenuItem generateSuperHybridItem = new JMenuItem("Generate schedule with Super Hybrid algorithm");
				generateSuperHybridItem.addActionListener(new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent e) {
						frame.startSuperHybrid();
					}
				});
				popup.add(generateSuperHybridItem);
				int row = table.rowAtPoint(e.getPoint());
				if (row >= 0 && row < table.getRowCount()) {
					final int index = table.convertRowIndexToModel(row);
					Schedule schedule = system.getSchedules().get(index);
					JMenuItem viewItem = new JMenuItem("View schedule " + schedule.getId());
					viewItem.addActionListener(new ActionListener() {
						@Override
						public void actionPerformed(ActionEvent e) {
							frame.viewSchedule(system.getSchedules().get(index));
						}
					});
					popup.add(viewItem);
					JMenuItem modifyItem = new JMenuItem("Modify schedule " + schedule.getId());
					modifyItem.addActionListener(new ActionListener() {
						@Override
						public void actionPerformed(ActionEvent e) {
							frame.modifySchedule(index);
						}
					});
					popup.add(modifyItem);
					JMenuItem deleteItem = new JMenuItem("Delete schedule " + schedule.getId());
					deleteItem.addActionListener(new ActionListener() {
						@Override
						public void actionPerformed(ActionEvent e) {
							if(system.removeSchedule(index)) {
								model.removeRow(index);
							}
						}
					});
					popup.add(deleteItem);
					table.setRowSelectionInterval(row, row);
				} else {
					table.clearSelection();
				}
				popup.show(e.getComponent(), e.getX(), e.getY());
			}
			else if(e.getClickCount()==2) {
				int row = table.rowAtPoint(e.getPoint());
				if (row >= 0 && row < table.getRowCount()) {
					final int index = table.convertRowIndexToModel(row);
					frame.viewSchedule(system.getSchedules().get(index));
				}
			}
		}
	}
}